package com.googlecode.beanfiles.translators;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.beanfiles.TranslationException;
import com.googlecode.beanfiles.TranslationNotice;


/**
 * A PropertyTranslator will be associated with a given bean property (property names are provided
 * by Maps and not necessarily stored within a PropertyTranslator), and convert between an input
 * type and an output type.
 */
public abstract class PropertyTranslator implements Cloneable {

    private List<TranslationNotice> notices = new ArrayList<TranslationNotice>();

    protected List<Integer> indexes = new ArrayList<Integer>();
    
    protected String propertyName;
    
    public PropertyTranslator() { }
    
    public PropertyTranslator(String propertyName) {
        this.propertyName = propertyName;
    }
    
    protected static Log log() {
        return LogFactory.getLog(PropertyTranslator.class);
    }

    public abstract Object read(Object i, Class<?> clazz);

    public abstract Object write(Object t);

    public void addTranslationNotice(TranslationNotice notice) {
        notices.add(notice);
    }

    public List<TranslationNotice> getTranslationNotices() {
        return notices;
    }
    
    public synchronized List<Integer> getIndexes() {
        return indexes;
    }
    
    public synchronized void addIndex(int index) {
        indexes.add(index);
    }

    /**
     * Whether or not this translator can be used to resolve a particular property.
     * @param propertyName a property name (perhaps nested)
     * @return true if if this translator can be used to resolve a given propertyName
     */
    public boolean resolvesProperty(String propertyName) {
        return propertyName.equals(this.propertyName);
    }
    
    /**
     * Certain translators may provide a list of indexes they are resolving for a given propertyName.
     * @param propertyName
     * @return
     */
    public List<Integer> getIndexes(String propertyName) {
        return indexes;
    }
    
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            log().error(e);
            throw new TranslationException("Property Translators must implement Cloneable");
        }
    }
}
